package com.huayu.languo.model.excp;

import com.huayu.languo.common.constant.AppConstants;
import com.huayu.languo.model.enums.LogLevel;
import com.huayu.languo.model.enums.ResultCode;
import org.apache.commons.lang3.StringUtils;


/**
 * @author 刘雄康
 * @version v1.0
 * @description 系统异常类基类
 * @date 2019年04月03日
 */
public abstract class AbstractAppException extends RuntimeException {

    private static final long serialVersionUID = 19492068467395846L;

    private String message = "";

    private ResultCode resultCode;

    private LogLevel logLevel = LogLevel.INFO;

    private transient Object data;

    private String debugMessage = "";

    private boolean areBuzExp = true;

    protected AbstractAppException(Exception e) {
        this(e, null);
    }

    protected AbstractAppException(Exception e, String eMsg) {
        super(e);
        if (e instanceof BizException) {
            BizException be1 = (BizException) e;
            this.message = be1.getMessage();
            this.resultCode = be1.getResultCode();
            this.logLevel = be1.getLogLevel();
            this.data = be1.getData();
            this.debugMessage = be1.getDebugMessage();
        } else {
            this.areBuzExp = false;
        }
        if (StringUtils.isNotEmpty(eMsg)) {
            this.message = eMsg;
        }
    }

    protected AbstractAppException(String msg, boolean areBuzExp) {
        super(msg);
        this.areBuzExp = areBuzExp;
    }

    public AbstractAppException(ResultCode resultCode) {
        this.resultCode = resultCode;
        this.message = resultCode.message();
    }

    public AbstractAppException(ResultCode resultCode, Object data) {
        this(resultCode);
        this.data = data;
    }

    public AbstractAppException(ResultCode resultCode, Object data, String msg) {
        this(resultCode);
        this.data = data;
        if (this.message.contains(AppConstants.MSG_PLACE)) {
            this.message = String.format(StringUtils.replace(this.message, AppConstants.MSG_PLACE, AppConstants.STR_FORMAT_PLACE), msg);
        } else {
            this.debugMessage = msg;
        }
    }

    public AbstractAppException(ResultCode resultCode, Object data, String formatMsg, Object... objects) {
        this(resultCode);
        this.data = data;
        if (formatMsg.contains(AppConstants.MSG_PLACE)) {
            formatMsg = String.format(StringUtils.replace(formatMsg, AppConstants.MSG_PLACE, AppConstants.STR_FORMAT_PLACE), objects);
        } else if (formatMsg.contains(AppConstants.STR_FORMAT_PLACE)) {
            formatMsg = String.format(formatMsg, objects);
        } else {
            //do noting
        }
        if (this.message.contains(AppConstants.MSG_PLACE)) {
            this.message = String.format(StringUtils.replace(this.message, AppConstants.MSG_PLACE, AppConstants.STR_FORMAT_PLACE), formatMsg);
        } else {
            this.debugMessage = formatMsg;
        }
    }

    @Override
    public String getMessage() {
        return message;
    }

    public ResultCode getResultCode() {
        return this.resultCode;
    }

    public Object getData() {
        return this.data;
    }

    public String getDebugMessage() {
        return debugMessage;
    }

    public AbstractAppException setDebugMessage(String debugMessage) {
        this.debugMessage = debugMessage;
        return this;
    }

    public LogLevel getLogLevel() {
        return logLevel;
    }

    public AbstractAppException setLogLevel(LogLevel logLevel) {
        this.logLevel = logLevel;
        return this;
    }

    public boolean areBuzExp() {
        return areBuzExp;
    }
}
